/*
 * @Copyright: 2017 www.yyfax.com Inc. All rights reserved.
 */
package com.yyfax.pay.third.facade.lianlian;

import static com.yyfax.framework.yyfax.enums.RspCodeEnum.COMMON_ERROR_UNKNOWN_EXCEPTION;
import static com.yyfax.pay.common.enums.PayRspCodeEnum.PAY_CODE_CHECK_SIGN_FAIL;
import static com.yyfax.pay.common.enums.PayRspCodeEnum.PAY_CODE_NOTIFY_FAIL;
import static com.yyfax.pay.common.enums.PayRspCodeEnum.PAY_CODE_PAY_FAIL;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang.NotImplementedException;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.yyfax.commons.json.JacksonUtil;
import com.yyfax.commons.lang.DateUtil;
import com.yyfax.commons.lang.Md5Util;
import com.yyfax.commons.lang.NumberUtil;
import com.yyfax.commons.lang.RSAUtil;
import com.yyfax.framework.yyfax.enums.TerminalEnum;
import com.yyfax.pay.common.enums.PayModeEnum;
import com.yyfax.pay.common.enums.PayRspCodeEnum;
import com.yyfax.pay.common.enums.PayTypeEnum;
import com.yyfax.pay.common.enums.PaymentEnum;
import com.yyfax.pay.common.exception.YYPayException;
import com.yyfax.pay.common.util.LianlianSignUtil;
import com.yyfax.pay.config.data.service.MerchantPaymentService;
import com.yyfax.pay.config.model.po.MerchantPaymentPO;
import com.yyfax.pay.third.model.to.lianlian.LianLianWebFormContent;
import com.yyfax.pay.third.model.to.lianlian.LianlianExt;
import com.yyfax.pay.third.model.to.lianlian.PayoutOrderLianlianContent;
import com.yyfax.pay.third.model.to.lianlian.PayoutOrderLianlianParams;
import com.yyfax.pay.third.model.to.lianlian.QueryCardBinLianLianContent;
import com.yyfax.pay.third.model.to.lianlian.QueryCardBinLianLianParams;
import com.yyfax.pay.third.model.to.lianlian.QueryPayOrderLianlianContent;
import com.yyfax.pay.third.model.to.lianlian.QueryPayOrderLianlianParams;
import com.yyfax.pay.third.model.to.lianlian.QueryPayOutOrderLianlianContent;
import com.yyfax.pay.third.model.to.lianlian.QueryPayOutOrderLianlianParams;
import com.yyfax.pay.third.model.to.lianlian.QueryUserBankcardContent;
import com.yyfax.pay.third.model.to.lianlian.QueryUserBankcardParams;
import com.yyfax.pay.third.model.to.yyfax.AuthenticationYYContent;
import com.yyfax.pay.third.model.to.yyfax.AuthenticationYYParams;
import com.yyfax.pay.third.model.to.yyfax.OrderNotifyContent;
import com.yyfax.pay.third.model.to.yyfax.OrderReturnContent;
import com.yyfax.pay.third.model.to.yyfax.PayOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.PayOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.PayoutBatchOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.PayoutBatchOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.PayoutOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.PayoutOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.QueryBatchPayoutOrderCheckYYContent;
import com.yyfax.pay.third.model.to.yyfax.QueryBatchPayoutOrderCheckYYParams;
import com.yyfax.pay.third.model.to.yyfax.QueryBatchPayoutOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.QueryBatchPayoutOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.QueryCardBinContent;
import com.yyfax.pay.third.model.to.yyfax.QueryCardBinParams;
import com.yyfax.pay.third.model.to.yyfax.QueryPayOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.QueryPayOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.QueryPayoutOrderYYContent;
import com.yyfax.pay.third.model.to.yyfax.QueryPayoutOrderYYParams;
import com.yyfax.pay.third.model.to.yyfax.SendAuthenticationVerifyCodeYYContent;
import com.yyfax.pay.third.model.to.yyfax.SendAuthenticationVerifyCodeYYParams;
import com.yyfax.pay.third.model.to.yyfax.SendVerifyCodeYYContent;
import com.yyfax.pay.third.model.to.yyfax.SendVerifyCodeYYParams;
import com.yyfax.pay.third.model.to.yyfax.WebFormYYContent;
import com.yyfax.pay.third.model.to.yyfax.WebFormYYParams;
import com.yyfax.pay.third.service.ThirdPayService;
import com.yyfax.pay.third.service.TransformService;

/**
 * 连连支付/代付接口外观
 *
 * @author jiangmy
 * @date 2017-04-11 10:39:53
 * @since v1.0.0
 */
public class LianlianFacade extends ThirdPayService {

	private Logger logger = LoggerFactory.getLogger(getClass());

	@Resource(name = "lianlianTransformService")
	private TransformService transformService;
	@Resource
	private LianlianApi lianlianApi;
	@Autowired
	private MerchantPaymentService merchantPaymentService;
	
	@PostConstruct
	private void init() {
		this.facadeName = "连连";
	}
	
	@Override
	public QueryPayOrderYYContent queryOrder(QueryPayOrderYYParams req) throws Exception {
		QueryPayOrderLianlianParams params = transformService.transformQueryPayOrderParams(req);
		QueryPayOrderLianlianContent content = lianlianApi.queryPayOrder(params);
		QueryPayOrderYYContent transformContent = transformService.transformQueryPayOrderContent(content);
		return transformContent;
	}

	@Override
	public SendAuthenticationVerifyCodeYYContent sendAuthenticationVerifyCode(SendAuthenticationVerifyCodeYYParams req) throws YYPayException {
		// 连连支付不支持
		throw new NotImplementedException("连连支付不支持");
	}

	@Override
	public AuthenticationYYContent authentication(AuthenticationYYParams req) throws YYPayException {
		// 连连支付不支持
		throw new NotImplementedException("连连支付不支持");
	}

	@Override
	public SendVerifyCodeYYContent sendVerifyCode(SendVerifyCodeYYParams req) throws YYPayException {
		// 连连支付不支持
		throw new NotImplementedException("连连支付不支持");
	}

	@Override
	public PayOrderYYContent payOrder(PayOrderYYParams req) throws YYPayException {
		// 连连支付不支持
		throw new NotImplementedException("连连支付不支持");
	}

	@Override
	public PayoutOrderYYContent payoutOrder(PayoutOrderYYParams req) throws Exception {

		PayoutOrderLianlianParams payoutOrderLianlianParams = transformService.transformPayoutOrderParams(req);
		PayoutOrderLianlianContent payoutOrderLianlianContent = lianlianApi.payout(payoutOrderLianlianParams);
		PayoutOrderYYContent payoutOrderYYContent = transformService.transformPayoutOrderContent(payoutOrderLianlianContent);

		String url = payoutOrderLianlianParams.getUrl();
		payoutOrderYYContent.setReqUrl(url);

		payoutOrderYYContent.setReqContent(payoutOrderLianlianContent.getReqContent());

		payoutOrderYYContent.setRspContent(payoutOrderLianlianContent.getRspContent());
		return payoutOrderYYContent;
	}

	@Override
	public PayoutBatchOrderYYContent payoutBatchOrder(PayoutBatchOrderYYParams req) throws YYPayException {
		// 连连代付不支持
		throw new NotImplementedException("连连代付不支持");
	}

	@Override
	public QueryBatchPayoutOrderYYContent queryBatchPayoutOrder(QueryBatchPayoutOrderYYParams req) throws YYPayException {
		// 连连代付不支持
		throw new NotImplementedException("连连代付不支持");
	}

	@Override
	public QueryBatchPayoutOrderCheckYYContent batchPayoutOrderCheck(QueryBatchPayoutOrderCheckYYParams req) throws YYPayException {
		// 连连代付不支持
		throw new NotImplementedException("连连代付不支持");
	}

	@Override
	public QueryCardBinContent queryCardBin(QueryCardBinParams req) throws Exception {
		QueryCardBinLianLianParams params = transformService.transformQueryCardBinParams(req);
		QueryCardBinLianLianContent content = lianlianApi.queryCardBin(params);
		QueryCardBinContent transformContent = transformService.transformQueryCardBinContent(content);
		transformContent.setCardNo(req.getCardNo());
		return transformContent;
	}

	@Override
	public WebFormYYContent<LianLianWebFormContent> transformWebForm(WebFormYYParams req) throws Exception {

		if (PayModeEnum.AUTH_PAY.getValue().equals(req.getPayMode())) {
			return transAuthPayWebForm(req);
		} else if (PayModeEnum.EBANK_PAY.getValue().equals(req.getPayMode())) {
			return transEbankPayWebForm(req);
		}

		return null;
	}

	private WebFormYYContent<LianLianWebFormContent> transAuthPayWebForm(WebFormYYParams req) throws Exception {
		WebFormYYContent<LianLianWebFormContent> transformContent = new WebFormYYContent<>();

		LianLianWebFormContent lianLianWebFormContent = new LianLianWebFormContent();
		LianlianExt lianlianExt = getMerchantInfo(req.getMerchantCode(), PayTypeEnum.PAY, PayModeEnum.AUTH_PAY);
		String registerTime = DateUtil.date2Str(DateUtil.str2DateTime(req.getRegisterTime()), "yyyyMMddHHmmss");

		// 检查连连是否已开户
		String noAgree = checkLianLian(lianlianExt, req.getUserId(), req.getCardNo());
		if (!StringUtils.isBlank(noAgree)) {
			lianLianWebFormContent.setNo_agree(noAgree);
		}
		lianLianWebFormContent.setCard_no(req.getCardNo());
		lianLianWebFormContent.setRisk_item(getRiskItem(req.getUserId(), req.getName(), req.getIdNo(), registerTime));
		lianLianWebFormContent.setId_no(req.getIdNo());
		lianLianWebFormContent.setAcct_name(req.getName());
		lianLianWebFormContent.setUser_id(req.getUserId());
		// 增加订单有效时间
		lianLianWebFormContent.setValid_order(lianlianExt.getValidOrder());
		// 异步回调地址
		lianLianWebFormContent.setNotify_url(lianlianExt.getNotifyUrl());
		lianLianWebFormContent.setNo_order(req.getPayOrderId());

		String orderTime = DateUtil.date2Str(DateUtil.str2DateTime(req.getOrderTime()), "yyyyMMddHHmmss");
		lianLianWebFormContent.setDt_order(orderTime);

		lianLianWebFormContent.setName_goods("友金所充值-投资");

		String moneyOrder = NumberUtil.fen2yuan(String.valueOf(req.getAmount()));
		lianLianWebFormContent.setMoney_order(moneyOrder);

		lianLianWebFormContent.setUrl_return(lianlianExt.getUrlReturn());

		lianLianWebFormContent.setBusi_partner(lianlianExt.getBusiPartner());
		lianLianWebFormContent.setId_type("0");

		lianLianWebFormContent.setPay_type(lianlianExt.getPayType());

		lianLianWebFormContent.setOid_partner(lianlianExt.getOidPartner());
		lianLianWebFormContent.setSign_type(lianlianExt.getSignType());
		lianLianWebFormContent.setPlatform(lianlianExt.getPlatForm());

		/** 组建充值报文 */
		if (TerminalEnum.PC.getValue().equals(req.getTerminal())) {
			// PC同步回调地址
			lianLianWebFormContent.setUserreq_ip(req.getUserIp());

			lianLianWebFormContent.setTimestamp(orderTime);
			lianLianWebFormContent.setVersion(lianlianExt.getVersionPC());


			JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(lianLianWebFormContent));
			this.createOrderSign(jsonObject, lianlianExt);

			lianLianWebFormContent = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<LianLianWebFormContent>() {
			});

			transformContent.setUrl(lianlianExt.getPayUrl());
		} else {

			lianLianWebFormContent.setBack_url(lianlianExt.getBackUrl());
			lianLianWebFormContent.setVersion(lianlianExt.getVersion());
			lianLianWebFormContent.setApp_request(lianlianExt.getAppRequest());

			JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(lianLianWebFormContent));
			this.createOrderSign(jsonObject, lianlianExt);

			lianLianWebFormContent = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<LianLianWebFormContent>() {
			});

			transformContent.setUrl(lianlianExt.getPayMobileUrl());
		}

		JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(lianLianWebFormContent));
		this.createOrderSign(jsonObject, lianlianExt);

		lianLianWebFormContent = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<LianLianWebFormContent>() {
		});

		transformContent.setForm(lianLianWebFormContent);
		transformContent.setNotifyUrl(lianlianExt.getNotifyUrl());
		transformContent.setReturnUrl(lianlianExt.getUrlReturn());
		return transformContent;
	}

	private WebFormYYContent<LianLianWebFormContent> transEbankPayWebForm(WebFormYYParams req) throws Exception {

		WebFormYYContent<LianLianWebFormContent> transformContent = new WebFormYYContent<>();

		LianLianWebFormContent lianLianWebFormContent = new LianLianWebFormContent();
		LianlianExt lianlianExt = getMerchantInfo(req.getMerchantCode(), PayTypeEnum.PAY, PayModeEnum.EBANK_PAY);
		String registerTime = DateUtil.date2Str(DateUtil.str2DateTime(req.getRegisterTime()), "yyyyMMddHHmmss");

		// 是否已经通过身份验证
		lianLianWebFormContent.setRisk_item(getRiskItem(req.getUserId(), req.getName(), req.getIdNo(), registerTime));
		lianLianWebFormContent.setUser_id(req.getUserId());
		// 异步回调地址
		lianLianWebFormContent.setNotify_url(lianlianExt.getNotifyUrl());
		lianLianWebFormContent.setNo_order(req.getPayOrderId());
		String orderTime = DateUtil.date2Str(DateUtil.str2DateTime(req.getOrderTime()), "yyyyMMddHHmmss");
		lianLianWebFormContent.setDt_order(orderTime);
		lianLianWebFormContent.setName_goods("友金所网银充值-投资");

		String moneyOrder = NumberUtil.fen2yuan(String.valueOf(req.getAmount()));
		lianLianWebFormContent.setMoney_order(moneyOrder);

		lianLianWebFormContent.setUrl_return(lianlianExt.getUrlReturn());

		lianLianWebFormContent.setUserreq_ip(req.getUserIp());
		lianLianWebFormContent.setTimestamp(orderTime);
		lianLianWebFormContent.setPay_type(lianlianExt.getPayType());

		lianLianWebFormContent.setBusi_partner(lianlianExt.getBusiPartner());
		lianLianWebFormContent.setVersion(lianlianExt.getVersionPC());
		lianLianWebFormContent.setOid_partner(lianlianExt.getOidPartner());
		lianLianWebFormContent.setSign_type(lianlianExt.getSignType());
		lianLianWebFormContent.setPlatform(lianlianExt.getPlatForm());
		JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(lianLianWebFormContent));
		this.createOrderSign(jsonObject, lianlianExt);

		lianLianWebFormContent = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<LianLianWebFormContent>() {
		});

		transformContent.setUrl(lianlianExt.getPayEbankUrl());
		transformContent.setForm(lianLianWebFormContent);
		transformContent.setNotifyUrl(lianlianExt.getNotifyUrl());
		transformContent.setReturnUrl(lianlianExt.getUrlReturn());
		return transformContent;
	}

	private String checkLianLian(LianlianExt lianlianExt, String userId, String card_no) throws Exception {
		/** 组建<查询签约>信息报文 */
		QueryUserBankcardParams params = new QueryUserBankcardParams();
		params.setUser_id(userId);
		params.setPay_type(lianlianExt.getPayType());
		params.setOffset("0");
		params.setCard_no(card_no);

		params.setOid_partner(lianlianExt.getOidPartner());
		params.setSign_type(lianlianExt.getSignType());
		params.setPlatform(lianlianExt.getPlatForm());

		JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(params));

		logger.info("查询签约进行加签");
		this.createOrderSign(jsonObject, lianlianExt);

		params = JSON.parseObject(jsonObject.toJSONString(), new TypeReference<QueryUserBankcardParams>() {
		});

		/** 解析<查询签约>报文，返回卡绑定信息，如果查询为空，签约号为空 */
		String noAgree = "";
		logger.info("--------发送查询签约报文{}", params);
		QueryUserBankcardContent queryUserBankcardContent = lianlianApi.readNoAgree(params, lianlianExt);
		if (queryUserBankcardContent != null && queryUserBankcardContent.getNo_agree() != null) {
			noAgree = queryUserBankcardContent.getNo_agree();
		}
		return noAgree;
	}

	@Override
	public OrderReturnContent transformPayOrderReturn(HttpServletRequest request) throws Exception {
		String message = ""; // 回显信息

		OrderReturnContent orderReturnContent = new OrderReturnContent();
		JSONObject result = readRequest(request);
		LianlianExt lianlianExt = getMerchantInfoId(result.getString("oid_partner"), PayTypeEnum.PAY, PayModeEnum.AUTH_PAY);
		logger.info("-----------------------------同步回调开始。。。。。。");
		try {
			if (this.checkReturnSign(result, lianlianExt)) {
				String resultState = result.getString("result_pay"); // 连连返回的交易状态
				String noOrder = result.getString("no_order"); // 连连返回的充值订单号
				

				logger.info("-----------------------------同步回调，[连连]银行卡投资，TransID is " + noOrder + "  result is " + resultState);
				// 校验连连返回的交易状态和交易流水
				if ("SUCCESS".equals(resultState) && noOrder.contains("_")) {
					logger.info("-----------------------------同步回调，[连连]银行卡投资，通知充值成功");
					logger.warn("-----------------------------同步回调，跳过YY理财数据库操作，防止同步和异步重复提交");

					message = "投资成功！";
					orderReturnContent.setResultCode(PayRspCodeEnum.SUCCESS.getValue());
					orderReturnContent.setResultMsg(message);
					
					

				} else {
					message = "投资失败！";

					logger.error("-----------------------------同步回调，[连连]银行卡投资失败，通知充值失败");
					orderReturnContent.setResultCode(PAY_CODE_PAY_FAIL.getValue());
					orderReturnContent.setResultMsg(message);
				}
				
				
				long yuan2fen = NumberUtil.yuan2fen(result.getDoubleValue("money_order"));
				
				orderReturnContent.setAmount(Integer.valueOf(String.valueOf(yuan2fen)));
				orderReturnContent.setPayOrderId(noOrder);
			} else {
				logger.error("-----------------------------同步回调，[连连]银行卡投资失败，通知签名异常");
				orderReturnContent.setResultCode(PAY_CODE_CHECK_SIGN_FAIL.getValue());
				orderReturnContent.setResultMsg(message);
			}
		} catch (Exception e) {
			// 缺省的异常信息，统一处理
			logger.error("-----------------------------同步回调，[连连]银行卡投资失败，{}", e);
			orderReturnContent.setResultCode(COMMON_ERROR_UNKNOWN_EXCEPTION.getValue());
			orderReturnContent.setResultMsg(e.getMessage());
		}
		return orderReturnContent;
	}

	@Override
	public OrderNotifyContent transformPayOrderNotify(HttpServletRequest request) throws Exception {
		JSONObject result = JSON.parseObject(readReqStr(request.getInputStream()));

		OrderNotifyContent orderNotifyContent = new OrderNotifyContent();

		String message = "";
		logger.info("-----------------------------异步回调开始。。。。。。");
		logger.info("异步回调内容:{}", result);


		LianlianExt lianlianExt = getMerchantInfoId(result.getString("oid_partner"), PayTypeEnum.PAY, PayModeEnum.AUTH_PAY);

		try {
			if (this.checkReturnSign(result, lianlianExt)) {
				String resultState = result.getString("result_pay"); // 连连返回的交易状态
				String noOrder = result.getString("no_order"); // 连连返回的充值订单号

				logger.info("-----------------------------异步回调，[连连]银行卡投资，TransID is " + noOrder + "  result is " + resultState);

				if ("SUCCESS".equals(resultState)) {
					// 交易成功
					orderNotifyContent.setResultCode(PayRspCodeEnum.SUCCESS.getValue());
					orderNotifyContent.setPayOrderId(noOrder);

					logger.info("-----------------------------异步回调，[连连]银行卡投资成功");

					message = "交易成功";

				} else {
					message = "交易失败，请重试";
					logger.error("-----------------------------异步回调，[连连]银行卡投资失败，通知充值失败");
					orderNotifyContent.setResultCode(PAY_CODE_NOTIFY_FAIL.getValue());
					orderNotifyContent.setPayOrderId(noOrder);
				}
			} else {
				message = "交易失败，请重试";
				logger.error("-----------------------------异步回调，[连连]银行卡投资失败，通知签名异常");
				orderNotifyContent.setResultCode(PAY_CODE_CHECK_SIGN_FAIL.getValue());
			}
			orderNotifyContent.setResultMsg(message);
		} catch (Exception e) {
			logger.error("-----------------------------异步回调，[连连]银行卡投资失败，{}", e);
			orderNotifyContent.setResultCode(COMMON_ERROR_UNKNOWN_EXCEPTION.getValue());
			orderNotifyContent.setResultMsg(e.getMessage());
		}

		JSONObject rspContent = new JSONObject();
		rspContent.put("ret_code", "0000");
		rspContent.put("ret_msg", "交易成功");
		orderNotifyContent.setRspContent(rspContent.toJSONString());
		return orderNotifyContent;
	}

	private String readReqStr(InputStream is) throws Exception {
		BufferedReader reader = null;
		StringBuilder sb = new StringBuilder();
		try {
			reader = new BufferedReader(new InputStreamReader(is, "utf-8"));
			String line = null;

			while ((line = reader.readLine()) != null) {
				sb.append(line);
			}
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			try {
				if (null != reader) {
					reader.close();
				}
			} catch (IOException e) {

			}
		}
		return sb.toString();
	}

	private JSONObject readRequest(HttpServletRequest request) throws Exception {

		JSONObject params = new JSONObject();
		params.put("oid_partner", request.getParameter("oid_partner"));
		params.put("sign_type", request.getParameter("sign_type"));
		params.put("sign", request.getParameter("sign"));
		params.put("dt_order", request.getParameter("dt_order"));
		params.put("no_order", request.getParameter("no_order"));
		params.put("oid_paybill", request.getParameter("oid_paybill"));
		params.put("money_order", request.getParameter("money_order"));
		params.put("result_pay", request.getParameter("result_pay"));
		params.put("pay_type", request.getParameter("pay_type"));
		params.put("settle_date", request.getParameter("settle_date"));
		params.put("info_order", request.getParameter("info_order"));
		params.put("bank_code", request.getParameter("bank_code"));

		return params;
	}

	private boolean checkReturnSign(JSONObject param, LianlianExt lianlianExt) throws Exception {
		boolean result = false;
		String sb = "";
		String mySign = "";
		String sign = param.getString("sign");
		sb = LianlianSignUtil.getSignStr(param);

		String sign_type = param.getString("sign_type");

		String key = null;
		boolean isTest = false;
		logger.info("sign_type is {} sign string is {} key is {}", sign_type, sb, key);
		if ("MD5".equals(sign_type)) {
			if (isTest) {
				key = "testKey";
			} else {
				key = lianlianExt.getMd5Key();
			}

			// Md5 加密
			sb += "&key=" + key;
			mySign = Md5Util.md5(sb);
			if (mySign != null && mySign.equals(sign)) {
				result = true;
			}
			logger.info("sign equals is {} sign is {}------mysign is {}", result, sign, mySign);
		} else {
			// rsa 加密
			result = RSAUtil.verify(lianlianExt.getPublicRsaKey(), sb, sign);
		}

		return result;
	}

	private String createOrderSign(JSONObject param, LianlianExt lianlianExt) throws Exception {
		String result = "";
		String sb = LianlianSignUtil.getSignStr(param);
		String sign_type = param.getString("sign_type");
		String key = null;
		boolean isTest = false;

		if ("MD5".equals(sign_type)) {
			if (isTest) {
				//todo 测试开关暂未实现
				key = "testKey";
			} else {
				key = lianlianExt.getMd5Key();
			}

			// Md5 加密
			sb += "&key=" + key;
			result = Md5Util.md5(sb);
			// logger.info("sign_type is {}, sign string is {}, key is {}", sign_type, sb, key);
		} else {
			if (isTest) {
				key = "testKey";
			} else {
				key = lianlianExt.getPrivateRsaKey();
			}

			// rsa 加密
			result = RSAUtil.sign(key, sb);
		}

		logger.info("sign_type is {}, sign string is {}, key is {}, create sign string is {}", sign_type, sb, key, sb);

		logger.info("result=====" + result);

		param.put("sign", result != null ? result.toLowerCase() : "");
		return result;
	}

	private LianlianExt getMerchantInfoId(String oidPartner, PayTypeEnum payType, PayModeEnum payMode) throws Exception {
		MerchantPaymentPO merchant = merchantPaymentService.queryByThirdMerchantId(oidPartner, PaymentEnum.LIAN_LIAN.getValue(),
				PayTypeEnum.PAY.getValue(), PayModeEnum.AUTH_PAY.getValue());
		LianlianExt lianlianExt = null;
		if (merchant == null) {
			logger.error("【lianlian】【pay】查询支付通过信息失败,商户信息为空,oidPartner:{}", oidPartner);
			throw new YYPayException(PAY_CODE_PAY_FAIL.getValue(), "查询支付通过信息失败,商户信息为空.");
		}
		if (StringUtils.isNotBlank(merchant.getExt())) {
			lianlianExt = JacksonUtil.nonullMapper.fromJson(merchant.getExt(), LianlianExt.class);
		} else {
			logger.error("【lianlian】【pay】支付商户扩展信息为空,oidPartner:{}", oidPartner);
			throw new YYPayException(PAY_CODE_PAY_FAIL.getValue(), "支付商户扩展信息为空");
		}
		logger.info("【lianlian】【pay】查询支付通过信息成功,merchant:{}", JacksonUtil.nonullMapper.toJson(merchant));

		return lianlianExt;
	}

	private LianlianExt getMerchantInfo(String merchantCode, PayTypeEnum payType, PayModeEnum payMode) throws Exception {
		MerchantPaymentPO merchant = merchantPaymentService.queryByThirdMerchantCode(merchantCode, PaymentEnum.LIAN_LIAN.getValue(),
				payType.getValue(), payMode.getValue());
		LianlianExt lianlianExt = null;
		if (merchant == null) {
			logger.error("【lianlian】【pay】查询支付通过信息失败,商户信息为空,merchantCode:{}", merchantCode);
			throw new YYPayException(PayRspCodeEnum.PAY_CODE_PAY_FAIL.getValue(), "查询支付通过信息失败,商户信息为空.");
		}
		if (StringUtils.isNotBlank(merchant.getExt())) {
			lianlianExt = JacksonUtil.nonullMapper.fromJson(merchant.getExt(), LianlianExt.class);
		} else {
			logger.error("【lianlian】【pay】支付商户扩展信息为空,merchantCode:{}", merchantCode);
			throw new YYPayException(PayRspCodeEnum.PAY_CODE_PAY_FAIL.getValue(), "支付商户扩展信息为空");
		}
		logger.info("【lianlian】【pay】查询支付通过信息成功,merchant:{}", JacksonUtil.nonullMapper.toJson(merchant));

		return lianlianExt;
	}

	private String getRiskItem(String userId, String name, String idNo, String registerTime) throws Exception {

		JSONObject riskItem = new JSONObject();
		riskItem.put("frms_ware_category", "2009");
		riskItem.put("user_info_mercht_userno", userId);// 用户在商户系统中的标识
		// todo 需测试不带user_info_mercht_userlogin是否会有问题
		// riskItem.put("user_info_mercht_userlogin", t6110.F02);//用户在商户系统中的登陆名（手机号、邮箱等标识）
		// if(t6110.F04!=null){
		// riskItem.put("user_info_bind_phone", t6110.F04);//绑定手机hao
		// }

		riskItem.put("user_info_dt_register", registerTime);// 注册时间
		riskItem.put("user_info_id_type", "0");

		riskItem.put("user_info_full_name", name);// 用户注册姓名
		riskItem.put("user_info_id_no", idNo);// 用户注册证件号码

		riskItem.put("user_info_identify_state", "1");// 是否实名认证
		riskItem.put("user_info_identify_type", "4");// 实名认证方式
		String json = riskItem.toString();
		return json;
	}

	@Override
	public OrderNotifyContent transformPayoutOrderNotify(HttpServletRequest request) throws Exception {
		JSONObject result = JSON.parseObject(readReqStr(request.getInputStream()));

		OrderNotifyContent orderNotifyContent = new OrderNotifyContent();

		String message = "";
		logger.info("--------------------------代付异步回调开始。。。。。。");
		logger.info("代付异步回调内容:{}", result);

		LianlianExt lianlianExt = getMerchantInfoId(result.getString("oid_partner"), PayTypeEnum.PAY_OUT, PayModeEnum.AUTH_PAY);

		try {
			if (this.checkReturnSign(result, lianlianExt)) {
				String resultState = result.getString("result_pay"); // 连连返回的交易状态
				String noOrder = result.getString("no_order"); // 连连返回的充值订单号
				String oidPayBill = result.getString("oid_paybill"); //连连支付支付单号

				logger.info("-----------------------------异步回调，[连连]代付，TransID is " + noOrder + "  result is " + resultState);

				if ("SUCCESS".equals(resultState)) {
					// 交易成功
					orderNotifyContent.setResultCode(PayRspCodeEnum.SUCCESS.getValue());
					orderNotifyContent.setPayOrderId(noOrder);
					orderNotifyContent.setSerialNo(oidPayBill);


					logger.info("-----------------------------异步回调，[连连]代付成功");

					message = "交易成功";
				} else {
					message = "交易失败，请重试";
					logger.error("-----------------------------异步回调，[连连]代付失败");
					orderNotifyContent.setResultCode(PAY_CODE_NOTIFY_FAIL.getValue());
					orderNotifyContent.setPayOrderId(noOrder);
				}
			} else {
				message = "交易失败，请重试";
				logger.error("-----------------------------异步回调，[连连]代付失败，通知签名异常");
				orderNotifyContent.setResultCode(PAY_CODE_CHECK_SIGN_FAIL.getValue());
			}
			orderNotifyContent.setResultMsg(message);
		} catch (Exception e) {
			logger.error("-----------------------------异步回调，[连连]代付失败，{}", e);
			orderNotifyContent.setResultCode(COMMON_ERROR_UNKNOWN_EXCEPTION.getValue());
			orderNotifyContent.setResultMsg(e.getMessage());
		}
		JSONObject rspContent = new JSONObject();
		rspContent.put("ret_code", "0000");
		rspContent.put("ret_msg", "交易成功");
		orderNotifyContent.setRspContent(rspContent.toJSONString());
		return orderNotifyContent;
	}

	@Override
	public QueryPayoutOrderYYContent queryPayoutOrder(QueryPayoutOrderYYParams req) throws Exception {
		QueryPayOutOrderLianlianParams params = transformService.transformQueryPayOutOrderParams(req);
		QueryPayOutOrderLianlianContent content = lianlianApi.queryPayOutOrder(params);
		QueryPayoutOrderYYContent transformContent = transformService.transformQueryPayOutOrderContent(content);
		return transformContent;
	}
}
